
package com.joysuch.wwyt;

import cn.zlg.common.springmvc.validate.DefaultJsonExceptionResponseBodyBuilder;
import cn.zlg.common.springmvc.validate.JsonExceptionResponseBodyBuilder;
import com.joysuch.wwyt.core.common.util.PropertiesHelper;
import com.joysuch.wwyt.core.common.util.PropertiesLoader;
import com.joysuch.wwyt.core.filter.TestBaseInfoFilter;
import com.joysuch.wwyt.core.security.ShiroDbRealm;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.*;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

@Configuration
@Profile(value = {"dev-zxh"})
public class ShiroTestConfig {
    @Primary
    @Bean("properties")
    public Properties properties() throws IOException {
        PropertiesLoader loader = new PropertiesLoader();
        loader.setFileEncoding("UTF-8");
        loader.setValue("classpath:conf.properties");
        Properties properties = loader.createProperties();
        return properties;
    }

    @Bean("propertiesHelper")
    public PropertiesHelper propertiesHelper() throws IOException {
        PropertiesHelper propertiesHelper = new PropertiesHelper();
        propertiesHelper.setProperties(properties());
        return propertiesHelper;
    }

    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean("shiroRealm")
    public Realm shiroRealm() {
        ShiroDbRealm realm = new ShiroDbRealm();
        realm.setAuthorizationCachingEnabled(false);
        return realm;
    }

    @Bean("shiroEhcacheManager")
    public EhCacheManager shiroEhCacheManager() throws IOException {
        EhCacheManager ehCacheManager = new EhCacheManager();
        String cacheManagerConfigFile = properties().getProperty("shiroCacheManagerConfigFile");
        ehCacheManager.setCacheManagerConfigFile(cacheManagerConfigFile);
        // ehCacheManager.setCacheManagerConfigFile("classpath:ehcache/shiro-ehcache.xml");
        return ehCacheManager;
    }

    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager() throws IOException {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm());
        securityManager.setCacheManager(shiroEhCacheManager());
        return securityManager;
    }

    @Bean("shiroFilter")
    @DependsOn("propertiesHelper")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(BeanFactory beanFactory) throws IOException {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager());
        factoryBean.setLoginUrl("/login.do");
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
        // TODO 待修复
        filters.put("backSite", new TestBaseInfoFilter(beanFactory));
        factoryBean.setFilters(filters);
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/bp/risk/bigScreen", "anon");
        filterChainDefinitionMap.put("/**", "backSite,anon");
        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return factoryBean;
    }

    // @Bean
    // public FilterRegistrationBean timerFilterRegistrationBean() {
    // FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
    // filterRegistration.setFilter(new TimerFilter());
    // filterRegistration.setEnabled(true);
    // filterRegistration.addUrlPatterns("/*");
    // filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
    // return filterRegistration;
    // }

    // @Bean
    // public FilterRegistrationBean jspDispatcherFilterRegistrationBean() {
    // FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
    // filterRegistration.setFilter(new JspDispatcherFilter());
    // filterRegistration.setEnabled(true);
    // filterRegistration.addInitParameter("prefix", "/jsp");
    // filterRegistration.addUrlPatterns("*.jsp");
    // filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);
    // return filterRegistration;
    // }

    @Bean
    public FilterRegistrationBean openEntityManagerInViewFilterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new OpenEntityManagerInViewFilter());
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }

    @Bean
    public FilterRegistrationBean shiroFilterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
        filterRegistration.setEnabled(true);
        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }

    @Bean
    public JsonExceptionResponseBodyBuilder exceptionReponseBuilder() {
        return new DefaultJsonExceptionResponseBodyBuilder();
    }
}
